﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace BLO.News
{
    public class News
    {
        DTO.News info;
        DAO.News newsDAO;
        
        public News()
        {
            this.newsDAO = new DAO.News();
            this.info = new DTO.News();
        }

        /// <summary>
        /// Create BLO.News instance by DTO.News object.
        /// </summary>
        /// <param name="newsInfo">DTO.News object as UserInfo.</param>
        /// <returns>New BLO.News object which has UserInfo is the input DTO.News.</returns>
        public static News InitNews(DTO.News newsInfo)
        {
            BLO.InfoType NewsType = (BLO.InfoType)newsInfo.Type;
            String className = "DTO.News." + NewsType.ToString();
            News news = (News)System.Activator.CreateInstance(Type.GetType(className));
            news.info = newsInfo;
            return news;
        }

        /// <summary>
        /// Create BLO.News instance.
        /// </summary>
        /// <param name="_NewsType">Type of News</param>
        /// <returns>New BLO.News object which has null UserInfo.</returns>
        public static News InitNews(int _NewsType)
        {
            BLO.InfoType NewsType = (BLO.InfoType)_NewsType;
            String className = "DTO.News." + NewsType.ToString();
            return (News) System.Activator.CreateInstance(Type.GetType(className));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="NewsType"></param>
        /// <returns></returns>
        public static News InitNews(BLO.InfoType InfoType)
        {
            String className = "DTO.News." + InfoType.ToString();
            return (News)System.Activator.CreateInstance(Type.GetType(className));
        }

        /// <summary>
        /// Get News's description.
        /// </summary>
        /// <returns>String that describe the news.</returns>
        public virtual String GetDescription() { return ""; }

        /// <summary>
        /// UserInfo
        /// </summary>
        public DTO.News Info
        {
            get { return this.info; }
            set { this.info = value; }
        }

        /// <summary>
        /// The link to this News's main page.
        /// </summary>
        public String Link
        {
            set { this.info.Link = value; }
            get 
            {
                if (this.info.Link == null)
                    return "#";
                else
                    return this.info.Link;
            }
        }

        /// <summary>
        /// Get main user whom this News talks about.
        /// </summary>
        public User User1
        {
            get { return new User(this.info.User1ID); }
        }

        /// <summary>
        /// Get the user that has some involkes with this news.
        /// </summary>
        public User User2
        {
            get { return new User(this.info.User2ID); }
        }

        /// <summary>
        /// Insert this news into database.
        /// </summary>
        public void Insert()
        {
            newsDAO.InsertNews(this.info);
        }

        /// <summary>
        /// Update information to database.
        /// </summary>
        public void Update()
        {
            newsDAO.UpdateNews(this.info);
        }

        /// <summary>
        /// Re-get all information from database about this news.
        /// </summary>
        public void Refresh()
        {
            this.info = newsDAO.GetNews(this.info.ID);
        }

        /// <summary>
        /// Delete this news from database.
        /// </summary>
        public void Delete()
        {
            newsDAO.DeleteNews(this.info);
        }

        /// <summary>
        /// Get all News instance from DB.
        /// </summary>
        /// <returns>List<> of all News instances.</returns>
        public List<News> GetAllNews()
        {
            List<DTO.News> newsDTOs = newsDAO.GetAllNews();
            List<News> newsBLOs = new List<News>();
            News temp;

            foreach (DTO.News newDTO in newsDTOs)
            {
                temp = InitNews(newDTO);
                newsBLOs.Add(temp);
            }

            return newsBLOs;
        }

        /// <summary>
        /// Get News instance from DB.
        /// </summary>
        /// <param name="ID">News ID</param>
        /// <returns>News instance which has the specific ID.</returns>
        public News GetNews(int ID)
        {
            return InitNews(newsDAO.GetNews(ID));
        }

        /// <summary>
        /// Get list of News by main UserID.
        /// </summary>
        /// <param name="UserID">ID of main user who the target newses talk about.</param>
        /// <returns>List of News instances.</returns>
        public List<News> GetNews(String UserID)
        {
            List<DTO.News> newsDTOs = newsDAO.GetNews(UserID);
            List<News> newsBLOs = new List<News>();
            News temp;

            foreach (DTO.News newsDTO in newsDTOs)
            {
                temp = InitNews(newsDTO);
                newsBLOs.Add(temp);
            }

            return newsBLOs;
        }

        /// <summary>
        /// Get list of News by main UserID.
        /// </summary>
        /// <param name="UserID">ID of main user who the target newses talk about.</param>
        /// <param name="IsRead">Whether these newses have been read or not.</param>
        /// <returns>List of News instances.</returns>
        public List<News> GetNews(String UserID, Boolean IsRead)
        {
            List<DTO.News> newsDTOs = newsDAO.GetNews(UserID, IsRead);
            List<News> newsBLOs = new List<News>();
            News temp;

            foreach (DTO.News newsDTO in newsDTOs)
            {
                temp = InitNews(newsDTO);
                newsBLOs.Add(temp);
            }

            return newsBLOs;
        }

        /// <summary>
        /// Get list of News which have some involkes with specific user.
        /// </summary>
        /// <param name="UserID">ID of the user who involkes with the news (The user can be User1 or User2)</param>
        /// <returns>List of News instances.</returns>
        public List<News> GetNewsHaveInvolke(String UserID)
        {
            List<DTO.News> newsDTOs = newsDAO.GetNewsHaveInvolke(UserID);
            List<News> newsBLOs = new List<News>();
            News temp;

            foreach (DTO.News newsDTO in newsDTOs)
            {
                temp = InitNews(newsDTO);
                newsBLOs.Add(temp);
            }

            return newsBLOs;
        }

        /// <summary>
        /// Get list of all unread News.
        /// </summary>
        /// <param name="UserID">The main user ID.</param>
        /// <returns>List of DTO.News instances.</returns>
        public List<News> GetUnreadNews(String UserID)
        {
            List<DTO.News> newsDTOs = newsDAO.GetUnreadNews(UserID);
            List<News> newsBLOs = new List<News>();
            News temp;

            foreach (DTO.News newsDTO in newsDTOs)
            {
                temp = InitNews(newsDTO);
                newsBLOs.Add(temp);
            }

            return newsBLOs;
        }
    }
}